package online.afeibaili.storebackendframework.service.impl

import online.afeibaili.storebackendframework.model.AccountEntity
import online.afeibaili.storebackendframework.model.ProductEntity
import online.afeibaili.storebackendframework.model.ShoppingCartEntity
import online.afeibaili.storebackendframework.model.json.ProductJsonMapper
import online.afeibaili.storebackendframework.repository.AccountRepository
import online.afeibaili.storebackendframework.repository.ProductRepository
import online.afeibaili.storebackendframework.repository.ShoppingCartRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import kotlin.jvm.optionals.getOrElse


/**
 * 购物车逻辑层
 *
 *@author AfeiBaili
 *@version 2025/10/20 15:35
 */

@Service
@Transactional
class ShoppingCartServiceImpl {

    @Autowired
    lateinit var repository: ShoppingCartRepository

    @Autowired
    lateinit var productRepository: ProductRepository

    @Autowired
    lateinit var accountRepository: AccountRepository

    fun create(shoppingCart: ShoppingCartEntity): ShoppingCartEntity {
        return repository.save(shoppingCart)
    }

    fun getOrCreate(accountId: String): ShoppingCartEntity? {
        accountRepository.findById(accountId).getOrElse { return null }

        return repository.findById(accountId).getOrElse {
            val entity = ShoppingCartEntity(accountId, "[]")
            repository.save(entity)
            entity
        }
    }

    fun addProduct(accountId: String, product: ProductJsonMapper): Pair<AccountEntity, ProductEntity>? {
        val accountEntity: AccountEntity = accountRepository.findById(accountId).getOrElse {
            return null
        }
        repository.findByAccountId(accountId)?.let {
            val entity: ProductEntity = productRepository.findById(product.productId).getOrElse {
                return null
            }
            val jsonMappers: MutableList<ProductJsonMapper> = ProductJsonMapper.toListObject(it.products)
            val json: String = ProductJsonMapper.toListJson(jsonMappers)
            it.products = json
            repository.save(it)
            return Pair(accountEntity, entity)
        }
        return null
    }

    fun deleteProduct(accountId: String, product: ProductJsonMapper): Pair<AccountEntity, ProductEntity>? {
        val accountEntity: AccountEntity = accountRepository.findById(accountId).getOrElse {
            return null
        }
        repository.findByAccountId(accountId)?.let {
            val productEntity: ProductEntity = productRepository.findById(product.productId).getOrElse {
                return null
            }
            val productJsonMappers: MutableList<ProductJsonMapper> = ProductJsonMapper.toListObject(it.products)
            val filter: List<ProductJsonMapper> = productJsonMappers.filter { productMapper ->
                if (productMapper.productId == product.productId) {
                    val int: Int = productMapper.count - product.count
                    if (int < 1) return@filter false
                    productMapper.count = int
                    return@filter true
                }
                true
            }
            it.products = ProductJsonMapper.toListJson(filter)
            repository.save(it)
            return Pair(accountEntity, productEntity)
        }
        return null
    }

    fun clearProducts(accountId: String): Boolean {
        accountRepository.findById(accountId).getOrElse {
            return false
        }
        repository.findByAccountId(accountId)?.let {
            it.products = "[]"
            repository.save(it)
            return true
        }
        return false
    }

    fun getProducts(accountId: String): List<ProductEntity> {
        val entity: ShoppingCartEntity = repository.findById(accountId).getOrElse {
            return listOf()
        }
        val productJsonMappers = ProductJsonMapper.toListObject(entity.products)
        val entities: List<ProductEntity> =
            productRepository.findByCreateTimeIn(productJsonMappers.map { it.productId })
        return entities
    }

    fun getById(accountId: String): ShoppingCartEntity? {
        return repository.findByAccountId(accountId)
    }
}